﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Microsoft.VisualStudio.CommandBars;
using EnvDTE80;
using dotNails.Util;
using dotNails.CodeGen.Models;
using System.Windows.Input;
using System.Windows.Controls;
using EnvDTE;

namespace dotNails.UI {
	public partial class MainWindow : System.Windows.Window, IUserControlParent {
		#region Properties
		protected ConfigData _configData;
		public DTE2 DTE { get; set; }
		public EnvDTE.AddIn AddInInstance { get; set; }
		public MenuManager MenuManager { get; set; }
		public CommandBarPopup PopupMenu { get; set; }
		#endregion Properties

		public MainWindow(DTE2 dte, EnvDTE.AddIn addInInstance, MenuManager menuManager, CommandBarPopup popupMenu) {
			InitializeComponent();

			DTE = dte;
			AddInInstance = addInInstance;
			MenuManager = menuManager;
			PopupMenu = popupMenu;

			_configData = LoadConfigData();

			this.PageFrame.Loaded += new RoutedEventHandler(PageFrame_Loaded);
		}

		protected void PageFrame_Loaded(object sender, RoutedEventArgs e) {
			// Find all dbmls in the solution
			List<DbmlData> dbmls = AddInUtil.GetAllDBMLsInSolution(DTE);

			DatabaseList databaseListUserControl = new DatabaseList(this, dbmls);
			LoadUserControl(databaseListUserControl);
		}

		protected ConfigData LoadConfigData() {
			ConfigData configData;

			string configFilePath = ConfigData.GetConfigFilePath(DTE.Solution.FileName);
			configData = new ConfigData(configFilePath);

			return configData;
		}

		#region Methods to handle chromeless behavior
		public override void OnApplyTemplate() {
			base.OnApplyTemplate();

			GetTemplatedChild<FrameworkElement>("WindowTitleBar").MouseLeftButtonDown += DoDragMove;
			GetTemplatedChild<Button>("WindowCloseButton").Click += Close;
		}

		private TElement GetTemplatedChild<TElement>(string elementName) where TElement : DependencyObject {
			var o = this.FindName(elementName);
			if (o == null) {
				throw new ArgumentException("Element name not found or the provided type is invalid.", elementName);
			}

			return (TElement)o;
		}

		private void Close(object sender, EventArgs e) {
			Close();
		}

		private void DoDragMove(object sender, MouseButtonEventArgs e) {
			DragMove();
		}
		#endregion Methods to handle chromeless behavior

		#region IUserControlParent Members
		public void LoadUserControl(System.Windows.Controls.UserControl userControl) {
			PageFrame.Child = userControl;
			IChildUserControl childUserControl = userControl as IChildUserControl;

			if (childUserControl != null) {
				childUserControl.Display();
			}
			else {
				throw new Exception("UserControls must implement IChildUserControl interface");
			}
		}

		public void RunCustomToolOnFile(string filePath) {
			ProjectItem dbmlProjectItem = AddInUtil.GetProjectItemByFilePath(DTE, filePath);

			AddInUtil.SetCustomToolOnProjectItem(dbmlProjectItem);
			AddInUtil.RunCustomToolOnProjectItem(dbmlProjectItem);
		}

		/// <summary>
		/// I'm very open to a better way of doing this - rather than the children telling their parent to close, but I don't know of one in WPF
		/// </summary>
		public void CloseWindow() {
			this.Close();
		}

		public void SetConfigData(ConfigData configData) {
			_configData = configData;
		}
		#endregion

		private void ConventionConfig(object sender, RoutedEventArgs e) {
			UserControl nextUserControl = new ConventionConfig(this, _configData);
			LoadUserControl(nextUserControl);
		}
	}
}
